﻿using Ebook.Data.Abstract;
using Ebook.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Linq;

namespace Ebook.Data.Concrete
{
    public class EfRepository<T> : IRepository<T> where T : class
    {
        public EbookContext DbContext { get; set; }

        public EfRepository(EbookContext dbContext)
        {
            DbContext = dbContext;

        }

        public IQueryable<T> Table
        {
            get
            {
                return DbContext.Set<T>();
            }
        }
        #region Utilities

        /// <summary>
        /// 捕捉错误
        /// </summary>
        /// <param name="exc">异常</param>
        /// <returns>Error</returns>
        protected string GetFullErrorText(DbEntityValidationException exc)
        {
            var msg = string.Empty;
            foreach (var validationErrors in exc.EntityValidationErrors)
                foreach (var error in validationErrors.ValidationErrors)
                    msg += string.Format("Property: {0} Error: {1}", error.PropertyName, error.ErrorMessage) + Environment.NewLine;
            return msg;
        }
        /// <summary>
        /// 保存上下文
        /// </summary>
        /// <returns></returns>
        public int Save()
        {
            return DbContext.SaveChanges();
        }


        #endregion
        public T GetById(int id)
        {
            return DbContext.Set<T>().Find(id);
        }
        public void Insert(T entity)
        {
            try
            {
                if (entity == null)
                {
                    throw new ArgumentNullException("entitie");
                }
                DbContext.Set<T>().Add(entity);
                Save();
            }
            catch (DbEntityValidationException dbEx)
            {
                throw new Exception(GetFullErrorText(dbEx), dbEx);
            }
        }
        public void Insert(IEnumerable<T> entities)
        {
            try
            {
                if (entities == null)
                {
                    throw new ArgumentNullException("entities");
                }
                DbContext.Set<T>().AddRange(entities);
                Save();
            }
            catch (DbEntityValidationException dbEx)
            {
                throw new Exception(GetFullErrorText(dbEx), dbEx);
            }

        }
        public void Update(T entity)
        {
            try
            {
                if (entity == null)
                {
                    throw new ArgumentNullException("entity");

                }
                DbContext.Set<T>().Attach(entity);
                DbContext.Entry<T>(entity).State = EntityState.Modified;
                Save();

            }
            catch (DbEntityValidationException dbEx)
            {
                throw new Exception(GetFullErrorText(dbEx), dbEx);
            }

        }
        public void Update(IEnumerable<T> entities)
        {
            try
            {
                if (entities == null)
                {
                    throw new ArgumentNullException("entities");
                }
                foreach (T entity in entities)
                {
                    DbContext.Set<T>().Attach(entity);
                    DbContext.Entry<T>(entity).State = EntityState.Modified;
                    Save();
                }
            }
            catch (DbEntityValidationException dbEx)
            {
                throw new Exception(GetFullErrorText(dbEx), dbEx);
            }

        }
        public void Delete(T entity)
        {
            try
            {
                if (entity == null)
                {
                    throw new ArgumentNullException("entity");

                }
                DbContext.Set<T>().Remove(entity);
                Save();
            }
            catch (DbEntityValidationException dbEx)
            {
                throw new Exception(GetFullErrorText(dbEx), dbEx);
            }

        }
        public void Delete(IEnumerable<T> entities)
        {
            try
            {
                if (entities == null)
                {
                    throw new ArgumentNullException("entities");
                }
                DbContext.Set<T>().RemoveRange(entities);
            }
            catch (DbEntityValidationException dbEx)
            {
                throw new Exception(GetFullErrorText(dbEx), dbEx);
            }
        }



    }
}
